package com.itheima.mobilesafe74.engine;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Debug;

import com.itheima.mobilesafe74.R;
import com.itheima.mobilesafe74.db.domain.ProcessInfo;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/6/2.
 */
public class ProcessInfoProvider {
     /**
     * @param ctx
     * @return 获取进程总数的方法
     */
    public static int getProcessCount(Context ctx){
        //1、获取activityManager
        ActivityManager am= (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        //2、获取正在运行进程的集合
        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses=am.getRunningAppProcesses();
        //3、返回集合的总数
        return runningAppProcesses.size();
    }


    /**
     * @param ctx
     * @return 返回可用内存数 （bytes）
     */
    public static long getAvailSpace(Context ctx){
        //1、获取activityManager
        ActivityManager am= (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        //2、构建存储可用内存的对象
        ActivityManager.MemoryInfo memoryInfo=new ActivityManager.MemoryInfo();
        //3、给memoryInfo对象赋（可用内存）值
        am.getMemoryInfo(memoryInfo);
        //4、获取memoryInfo中相应可用内存大小
        return memoryInfo.availMem;
    }

    /**
     * @param ctx
     * @return 返回可用内存数 （byte） 返回0说明异常
     */
    public static long getTotalSpace(Context ctx){
        /*//1、获取activityManager
        ActivityManager am= (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        //2、构建存储可用内存的对象
        ActivityManager.MemoryInfo memoryInfo=new ActivityManager.MemoryInfo();
        //3、给memoryInfo对象赋（可用内存）值
        am.getMemoryInfo(memoryInfo);
        //4、获取memoryInfo中相应可用内存大小
        return memoryInfo.totalMem;*/

        FileReader fileReader=null;
        BufferedReader bufferedReader=null;
        //内存大小写入文件，读取proc/meminfo文件，读取第一行，获取数字字符，转换成bytes返回
        try {
            fileReader=new FileReader("proc/meminfo");
            bufferedReader=new BufferedReader(fileReader);
            String lineone=bufferedReader.readLine();
            //将字符串转换成字符的数组
            char[] charArray=lineone.toCharArray();
            //循环遍历每一个字符，如果此字符的ASCII码在0-9的区域内，说明此字符有效
            StringBuffer stringBuffer=new StringBuffer();
            for (char c:charArray){
                if (c>='0' && c<='9'){
                    stringBuffer.append(c);
                }
            }
            return Long.parseLong(stringBuffer.toString())*1024;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (fileReader!=null && bufferedReader!=null){
                try {
                    fileReader.close();
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return 0;
    }

    /**
     * @param ctx
     * @return 获取当前手机进程相关信息
     */
    public static List<ProcessInfo> getProcessInfo(Context ctx){
        List<ProcessInfo> processInfoList=new ArrayList<ProcessInfo>();
        //1、activityManager管理者对象和PackageManager管理者对象
        ActivityManager am= (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        PackageManager pm=ctx.getPackageManager();
        //2、获取正在运行的进程集合
        List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfos=am.getRunningAppProcesses();

        //3、循环遍历上诉集合，获取进程相关信息（名称，包名，图标，使用内存大小，是否为系统进程（状态机））
        for (ActivityManager.RunningAppProcessInfo info:runningAppProcessInfos){
            ProcessInfo processInfo=new ProcessInfo();
            //4、获取进程的名称==应用的包名
            processInfo.packageName=info.processName;
            //5、获取进程占用的内存大小（传递一个进程对应的pid数组）
            Debug.MemoryInfo[] processMemoryInfo=am.getProcessMemoryInfo(new int[]{info.pid});
            //6、返回数组中索引位置为0的对象，为当前进程的内存信息的对象
            Debug.MemoryInfo memoryInfo = processMemoryInfo[0];
            //7、获取已使用的大小
            processInfo.memSize=memoryInfo.getTotalPrivateDirty()*1024;

            try {
                //8、获取应用的名称
                ApplicationInfo applicationInfo=pm.getApplicationInfo(processInfo.packageName,0);
                processInfo.name=applicationInfo.loadLabel(pm).toString();
                //9、获取应用的图标
                processInfo.icon=applicationInfo.loadIcon(pm);
                //10、判断是否为系统进程
                if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)==ApplicationInfo.FLAG_SYSTEM){
                    processInfo.isSystem=true;
                }else {
                    processInfo.isSystem=false;
                }
            } catch (PackageManager.NameNotFoundException e) {
                //需要处理
                processInfo.name=info.processName;
                processInfo.icon=ctx.getResources().getDrawable(R.mipmap.ic_launcher);
                processInfo.isSystem=true;
                e.printStackTrace();
            }
            processInfoList.add(processInfo);
        }
        return processInfoList;
    }

    /**
     * 杀进程的方法
     * @param ctx 上下文的环境
     * @param processInfo 杀死进程所在的javabean对象
     */
    public static void killProcess(Context ctx,ProcessInfo processInfo) {
        //1、获取activityManager
        ActivityManager am= (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        //2、杀死指定包名进程（权限）
        am.killBackgroundProcesses(processInfo.packageName);

    }

    /**
     * 杀死所有的进程
     * @param ctx 上下文环境
     */
    public static void killAll(Context ctx) {
        //1、activityManager管理者对象
        ActivityManager am= (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        //2、获取正在运行的进程集合
        List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfos=am.getRunningAppProcesses();
        //3、循环遍历所有进程，并且杀死
        for (ActivityManager.RunningAppProcessInfo info:runningAppProcessInfos){
            //4、除了手机卫士以外，把其他进程杀死
            if (info.processName.equals(ctx.getPackageName())){
                //如果匹配上手机卫士，则需要跳出本次循环，继续下一次循环
                continue;
            }
            am.killBackgroundProcesses(info.processName);
        }
    }
}
